using System.Collections.Generic;
using Entitas;
using UnityEngine;

public sealed class CreateSystem : IInitializeSystem, ITearDownSystem
{
    private readonly IViewService _viewService;

    public CreateSystem(IViewService viewService)
    {
        _viewService = viewService;
    }

    private GameEntity CreatePlayer(int inputId, Vector3 position, Vector3 forward)
    {
        var e = Contexts.sharedInstance.game.CreateEntity();
        _viewService.CreatePlayerView(e);
        e.AddTransform(position, forward, new SmootherForward(GameDefine.SAMPLES_FOR_SMOOTHING, forward));
        e.AddVelocity(Vector3.zero, 3.0f);
        e.AddAccelerate(Vector3.zero, 3.0f);
        e.AddInput(inputId, new InputOp());
        e.AddColliderRadius(0.3f);

        e.isTarget = true;
        if (Contexts.sharedInstance.game.recordGlobal.recordMode)
        {
            e.AddRecord(inputId, new List<InputOp>());
        }

        return e;
    }

    private GameEntity CreateRobot(Vector3 position, Vector3 forward, BehaviorType behaviours, Vector3 offset)
    {
        var e = Contexts.sharedInstance.game.CreateEntity();
        _viewService.CreatePlayerView(e);
        e.AddTransform(position, forward, new SmootherForward(GameDefine.SAMPLES_FOR_SMOOTHING, forward));
        e.AddVelocity(Vector3.zero, 2.0f);
        e.AddAccelerate(Vector3.zero, 2.0f);
        e.AddColliderRadius(0.3f);

        WanderParams wanderParams = new WanderParams();
        wanderParams.wanderDistance = 3.0f;
        wanderParams.wanderJitter = 3.0f;
        wanderParams.wanderRadius = 1.0f;
        wanderParams.wanderTarget = new Vector3(0.0f, 0.0f, wanderParams.wanderRadius);

        Path path = new Path(
            new List<Vector3>(
                new Vector3[] {Vector3.left * 5, Vector3.forward * 5, Vector3.right * 5, Vector3.back * 5}),
            true);

        e.AddBehavior(behaviours, wanderParams, path, offset);

        return e;
    }

    private GameEntity CreateWall(Vector3 from, Vector3 to)
    {
        Vector3 normal = Vector3.Cross(Vector3.up, to - from).normalized;
        var e = Contexts.sharedInstance.game.CreateEntity();
        e.AddWall(from, to, normal);
        _viewService.CreateWallView(e);
        return e;
    }

    private GameEntity CreateTurrent(Vector3 pos, float radius)
    {
        var e = Contexts.sharedInstance.game.CreateEntity();
        e.AddTransform(pos, Vector3.forward, null);
        e.AddColliderRadius(radius);
        _viewService.CreateTurrentView(e);
        return e;
    }

    private GameEntity CreateThrone(Vector3 pos, float radius)
    {
        var e = Contexts.sharedInstance.game.CreateEntity();
        e.AddTransform(pos, Vector3.zero, null);
        e.AddColliderRadius(radius);
        _viewService.CreateThroneView(e);
        return e;
    }

    private GameEntity CreateSpawn(Vector3 pos, Vector3 destination)
    {
        var e = Contexts.sharedInstance.game.CreateEntity();
        e.AddTransform(pos, Vector3.zero, null);
        e.AddSpawn(10, 0, destination);
        _viewService.CreateSpawnView(e);
        return e;
    }

    public void Initialize()
    {
        CreatePlayer(1, Vector3.forward, Vector3.left);
        // for (int i = 0; i < 20; i++)
        // {
        //     int posX = Contexts.sharedInstance.game.random.random.Next(-(int) GameDefine.WORLD_SIZEX / 2,
        //         (int) GameDefine.WORLD_SIZEX / 2);
        //     int posZ = Contexts.sharedInstance.game.random.random.Next(-(int) GameDefine.WORLD_SIZEZ / 2,
        //         (int) GameDefine.WORLD_SIZEZ / 2);
        //     Vector3 pos = new Vector3(posX, 0, posZ);
        //
        //     var e2 = CreateRobot(pos, Vector3.forward,
        //         BehaviorType.WallAvoidance | BehaviorType.Separation |
        //         BehaviorType.Wander, Vector3.left);
        // }

        float halfWorldSizeX = GameDefine.WORLD_SIZEX / 2;
        float halfWorldSizeZ = GameDefine.WORLD_SIZEZ / 2;

        Vector3 wallPoint1 = new Vector3(-halfWorldSizeX, 0f, -halfWorldSizeZ);
        Vector3 wallPoint2 = new Vector3(-halfWorldSizeX, 0f, halfWorldSizeZ);
        Vector3 wallPoint3 = new Vector3(halfWorldSizeX, 0f, halfWorldSizeZ);
        Vector3 wallPoint4 = new Vector3(halfWorldSizeX, 0f, -halfWorldSizeZ);

        // fense
        CreateWall(wallPoint1,
            wallPoint2);

        CreateWall(wallPoint2,
            wallPoint3);

        CreateWall(wallPoint3,
            wallPoint4);

        CreateWall(wallPoint4,
            wallPoint1);

        // wall
        Vector3 p1 = new Vector3(-4, 0, -20);
        Vector3 p2 = new Vector3(-4, 0, -12);
        Vector3 p3 = new Vector3(p1.z, 0, p1.x);
        Vector3 p4 = new Vector3(p2.z, 0, p2.x);

        Vector3 p5 = -p1;
        Vector3 p6 = -p2;
        Vector3 p7 = -p3;
        Vector3 p8 = -p4;

        CreateWall(p2, p1);
        CreateWall(p3, p4);

        CreateWall(p6, p5);
        CreateWall(p7, p8);
        
        CreateWall(p8, p2);
        CreateWall(p4, p6);
        
        Vector3 t0 = new Vector3(-14, 0, -14);
        Vector3 t1 = new Vector3(-8, 0, -8);
        Vector3 t2 = new Vector3(-4, 0, -4);
        Vector3 t3 = new Vector3(-12, 0, -12);
        float turrentRadius = 1.0f;
        float throneRadius = 2.0f;
        // blue team 
        CreateThrone(t0, throneRadius);
        CreateTurrent(t1, turrentRadius);
        CreateTurrent(t2, turrentRadius);
        CreateSpawn(t3, -t3);
        
        // red team 
        CreateThrone(-t0, throneRadius);
        CreateTurrent(-t1, turrentRadius);
        CreateTurrent(-t2, turrentRadius);
        CreateSpawn(-t3, t3);

    }

    public void TearDown()
    {
        // var entities = Contexts.sharedInstance.game.GetEntities(GameMatcher.View);
        // foreach (var e in entities)
        // {
        //     e.view.gameObject.Destroy();
        // }
        //
        // entities = Contexts.sharedInstance.game.GetEntities(GameMatcher.ViewWall);
        // foreach (var e in entities)
        // {
        //     e.viewWall.wallObject.Destroy();
        // }
    }
}